<?php


namespace app\common\model;


use app\admin\model\Recharge;
use think\Cache;
use think\Db;

class Reword
{

    //检测充值订单剩余待抵扣金额
    public static function checkMoney()
    {

        $map = [
            'is_fen' => 2,
            'is_check' => 0,
            'isNeedShare' => 1,
        ];
        $end = strtotime(date('Y-m-d'));
        $list = Db::table('recharge')
            ->where($map)
            ->where('createtime','<',$end)
            //->where('check_amount','<',0.01)
            ->limit(50)
            ->select();
        log_print('检测剩余抵扣金额');
        log_print(Db::table('recharge')->getLastSql());
        foreach($list as $v){
            AgentShare::checkFenMoney($v['mchId'],$v['chnltrxid']);
        }

        $map = [
            'is_fen' => 2,
            'is_check' => 1,
            'isNeedShare' => 1,
        ];
        $list2 = Db::table('recharge')
            ->where($map)
            ->where('createtime','<',$end)
            ->where('check_amount','>',0.01)
            ->select();
        foreach($list2 as $vv){
            $update = [
                'is_check' => 0,
                'is_fen' => 1,
                'have_fee' => $vv['check_amount'],
            ];
            Db::table('recharge')->where('id',$vv['id'])->update($update);
        }

    }
    /**
     * 1:00 ~2:00
    预处理订单

    2:00 ~  3:00
    调用分账接口

    4:00~ 6:00
    查询分账结果
    更新分账明细
     * 6:00-8:00
     * 检测订单是否已经分账成功
     *
     */
    //加测这个订单是否全部分账完成，如果是，把订单状态更新为已分账
    public static function checkFenStatus()
    {
        $h = date('H');
        if($h >= 6 && $h < 8){

        }
        $map = [
            'is_pre' => 1,
            'is_check'=>0,
            'isNeedShare' => 1,
        ];
        $list = Db::table('shopro_order_bill')
            ->where($map)
            ->limit(100)
            //->where('fz_real_money','>',0)
            //->whereNotNull('fz_number')
            ->select();
        foreach($list as $v){
            $count1 = Db::table('shopro_order_bill_log')
                ->where('bill_id',$v['id'])
                ->count();
            $smap = [
                'bill_id' => $v['id'],
                'is_success' => 1,
            ];
            $count2 = Db::table('shopro_order_bill_log')->where($smap)
                //->where('fz_real_money','>',0)
                ->count();
            if($count1 == $count2 && $count2>0){
                $up = [
                    'status' => 1,
                    'is_check' => 1,
                    'check_res' => 1,
                    'fz_time' => time(),
                ];
            }else{
                $up = [
                    'is_check' => 1,
                ];
            }
            Db::table('shopro_order_bill')->where('id',$v['id'])->update($up);
        }

    }

    //批量执行预分账逻辑
    public static function batchFen($order_sn = '')
    {
        //在这个时间段才执行批量分账预处理
        $h = date('H');
        if($h >= 1 && $h < 2){

        }
        //$order_sn = '';
        self::getOrder($order_sn);
    }

    public static function checkOrder()
    {
        //检测昨天的订单
        Db::query('update `shopro_order_bill` set is_pre = 0 where is_pre = 1 and is_check = 0 and id not in (select bill_id from shopro_order_bill_log)');
        $end = time()-300;
        $map = [
            'is_send' => 0,
            'is_two' => 0,
        ];
        $list = BillLog::where($map)
            ->whereNotNull('mchId')
            ->whereNotNull('fz_number')
            ->where('createtime' , '<' ,$end)
            ->group('order_sn')
            ->select();
        log_print('分账前二次检测start');
        log_print('二次检测'.(new BillLog())->getLastSql());
        Db::startTrans();
        try{
            foreach($list as $v){
                $billSum = Db::table('shopro_order_bill')
                    ->where('order_sn',$v['order_sn'])
                    ->sum('fz_real_money');
                log_print('账单订单号'.$v['order_sn'].'billsum'.$billSum);
                log_print(Db::table('shopro_order_bill')->getLastSql());
                $fenSum =  BillLog::where('order_sn',$v['order_sn'])->sum('fen_fee');
                log_print('分账订单号'.$v['order_sn'].'$fenSum'.$fenSum);
                log_print((new BillLog())->getLastSql());
                $res = $billSum - $fenSum;
                $res = abs($res);
                log_print('abs'.$res);
                if($res > 0.05){
                    log_print($v['order_sn'].'二次检测异常');
                    $yichang =  BillLog::where('order_sn',$v['order_sn'])->select();
                    log_print('异常数据',collection($yichang)->toArray());
                    foreach($yichang as $vv){
                        $recharge = Recharge::get($vv['recharge_id']);
                        if($recharge){
                            $recharge->is_fen = 1;
                            $recharge->have_fee += $vv['fen_fee'];
                            $recharge->save();
                            log_print('退回扣款'.$recharge->getLastSql());
                            //删除账单
                            //退回 bill 表is_pre状态
                        }
                        //
                        Db::table('shopro_order_bill')
                            ->where('id',$vv['bill_id'])
                            ->update(['is_pre' => 0]);
                        log_print('bill_id 状态恢复'.$vv['bill_id'],Db::table('shopro_order_bill')->getLastSql());
                    }
                    $dmap = [
                        'order_sn' => $v['order_sn'],
                        'is_send' => 0,
                    ];
                    BillLog::where($dmap)->delete(); //删除异常账单
                    log_print('异常数据删除',(new BillLog())->getLastSql());
                }else{
                    log_print($v['order_sn'].'二次检测正常');
                    Db::table('shopro_order_bill_log')
                        ->where('order_sn',$v['order_sn'])
                        ->update(['is_two' => 1]);
                    log_print('正常数据',Db::table('shopro_order_bill_log')->getLastSql());
                }
            }
            log_print('分账前二次检测end');
            Db::commit();
        } catch (\Exception $e) {
            log_print('二次检测回滚');
            log_print($e->getMessage());
            // 回滚事务
            Db::rollback();
        }
    }



    //批量发放分账
    public static function batchSend()
    {
        $h = date('H');
        if($h >= 2 && $h < 3){

        }
        self::checkOrder();
        //die();
        $end = time()-300;
        $map = [
            'is_send' => 0,
            'is_two' =>1,
        ];
        $list = BillLog::where($map)
            ->whereNotNull('mchId')
            ->whereNotNull('fz_number')
            ->where('createtime' , '<' ,$end)
            ->limit(200)
            ->select();
        //print_r(collection($list)->toArray());die();
        //这个订单的金额是否足
        foreach($list as $v){
            AgentShare::sendFen($v);
        }
    }

    //批量检测分账结果
    public static function batchCheck()
    {
        $h = date('H');

        //if($h >= 4 && $h < 6){
        //}
            $map = [
                'is_send' => 1,
                'is_check'=>0,
                'is_success' => 0,
            ];
            $end = time()-300;
            $list = BillLog::where($map)
                ->limit(200)
                ->where('createtime' , '<' ,$end)
                ->select();
            foreach ($list as $v){
                $row = AgentShare::checkFen($v);
            }

    }

    //执行分账
    public static function sendFen()
    {
        $map = [
            "is_send" => 0,
        ];
        $list = BillLog::where($map)
            ->group('order_sn')
            ->limit(5)
            ->select();
        foreach($list as $v){
            if($v['mchId'] && $v['fz_number']){
                //建立账号绑定关系
                $res = AgentShare::bindAccount($v['mchId'],$v['fz_number']);
                if($res){
                    //发放分账
                    AgentShare::sendFen($v);
                    Db::table('shopro_order_bill_log')->where('id',$v['id'])->update(['is_send' => 1]);
                }
            }
        }
    }
    //执行预处理生成分账数据
    public static function getOrder($order_sn = '')
    {
        $map = [
            'type' =>(string)"0", //0=钱包
            "status"=>0, //0=未入账
            "is_pre" => 0,
        ];
        if(!empty($order_sn)){
           $map += [
               "order_sn" => $order_sn,
           ];
        }
        $end = strtotime(date('Y-m-d'));
        $list = Db::table('shopro_order_bill')
            ->where($map)
            ->where('fz_real_money','>',0)
            ->where('isNeedShare',1)
            ->where('paytime',"<",$end)
            ->whereNotNull('fz_number')
            ->order('id asc')
            ->limit(100)
            ->select();
        //echo Db::table('shopro_order_bill')->getLastSql();
        log_print('预分账查询订单');
        log_print(Db::table('shopro_order_bill')->getLastSql());
        //var_dump($list);
        log_print('订单ID',array_column($list,'id'));
        //log_print('订单集合',$list);
        // 启动事务
        Db::startTrans();
        try{
            foreach($list as $v){
                self::preLog2($v);
            }
            Db::commit();
        } catch (\Exception $e) {
            log_print('回滚失败');
            log_print($e->getMessage());
            // 回滚事务
            Db::rollback();
        }


    }

    public static function preLog2($order)
    {
        $user_id = $order['user_id'];
        $fz_money = $order['fz_real_money']; //分账金额
        $smap = [
            "user_id" => $user_id,
            "status" => 1,
            "sharableAmount" => 0,
            'isNeedShare' => 1,
        ];
        $end = strtotime(date('Y-m-d'));
        $list = Db::table('recharge')
            ->where($smap)
            ->whereNotNull('chnltrxid')
            ->whereNotNull('mchId')
            ->where('createtime','<',$end)
            ->order('id asc')
            ->select();
        log_print('充值记录',array_column($list,'id'));
        log_print('充值记录', Db::table('recharge')->getLastSql());
        //查询待分账金额,更新
        foreach($list as $v){
            if($v['sharableAmount'] == 0){
                AgentShare::findFenMoney($v['mchId'],$v['chnltrxid'],$v['id']);
            }
        }
        $smap = [
            "user_id" => $user_id,
            "status" => 1,
            "is_fen" => ['in',[0,1]],
            //"sharableAmount" => 0,
            'isNeedShare' => 1,
        ];
        $sum = Db::table('recharge')
            ->where($smap)
            ->whereNotNull('chnltrxid')
            ->whereNotNull('mchId')
            ->where('createtime','<',$end)
            ->sum('sharableAmount');
        log_print('充值可用总额sum'.$sum.'-'.Db::table('recharge')->getLastSql());
        $orderAmount = Db::table('shopro_order_bill')
            ->where('order_sn',$order['order_sn'])
            ->sum('fz_real_money');
        log_print('账单总额'.$orderAmount.'-'.Db::table('shopro_order_bill')->getLastSql());
        $res = func_sprintf($sum-$orderAmount);
        $res1 = abs($res);
        if( $res1 > $sum+0.05){
            log_print('bill_id-'.$order['id'].'误差金额过大'.$res.'-执行预分账失败');
            log_print('sum-'.$sum.'-$orderAmount'.$orderAmount);
            log_print('sumSQL-'.Db::table('recharge')->getLastSql());
            log_print('$orderAmountSQL-'.Db::table('shopro_order_bill')->getLastSql());
            return false;
        }
        if($res1 >0 && $res1<=0.05){
            $bill = Db::table('shopro_order_bill')
                ->where('order_sn',$order['order_sn'])
                ->order('fz_real_money desc')
                ->find();
            $wucha = [
                'wucha_money' => $res,
                'fz_real_money' => func_sprintf($bill['fz_real_money']+$res),
            ];
            Db::table('shopro_order_bill')
                ->where('id',$bill['id'])
                ->update($wucha);
            log_print('误差计算'.Db::table('shopro_order_bill')->getLastSql());
        }
        $up2 = [
            'is_pre' => 1,
        ];
        Db::table('shopro_order_bill')
            ->where('id',$order['id'])
            ->update($up2);

        $map = [
            "user_id" => $user_id,
            "status" => 1,
            "is_fen" => ['in',[0,1]],
            'isNeedShare' => 1,
        ];
        $list = Db::table('recharge')
            ->where($map)
            ->where('createtime','<',$end)
            ->order('id desc')
            ->select();
        log_print('可用核销充值记录'. Db::table('recharge')->getLastSql());
        log_print('可用核销充值记录ID',array_column($list,'id'));
        foreach($list as $k=>$v){
            if($v['is_fen'] == 1){
                $use_sum = $v['have_fee'];
            } else {
                $use_sum = $v['sharableAmount'];
            }
            $fen_sn = create_sn('F').$k.rand(1000,9999);
            if($use_sum >= $fz_money && $fz_money > 0){

                $have_fee = bcsub($use_sum, $fz_money,2);
                $log = [
                    'order_sn' => $order['order_sn'],
                    'bill_id' => $order['id'],
                    'fz_account' => $order['fz_account'],
                    'fz_number' => $order['fz_number'],
                    'mchId' => $v['mchId'],
                    'chnltrxid' => $v['chnltrxid'],
                    'recharge_id' => $v['id'],
                    'recharge_order_sn' => $v['order_sn'],
                    'fen_fee' => $fz_money,
                    'all_fee' => $v['sharableAmount'],
                    'sup_fee' => $have_fee,
                    'fen_sn' => $fen_sn,
                ];
                BillLog::create($log);
                log_print('账单sql2',(new BillLog())->getLastSql());
                $is_fen = 1;

                if($have_fee == 0){
                    $is_fen = 2;
                }
                $up = [
                    'is_fen' => $is_fen,
                    'have_fee' =>  $have_fee,
                ];
                log_print('充值记录'.$v['id'].'总余额'.$v['sharableAmount'].'-可用余额'.$use_sum.'分账用去'.$fz_money.'-剩余'.$up['have_fee'].'-is_fen='.$v['is_fen']);
                Db::table('recharge')
                    ->where('id',$v['id'])
                    ->update($up);
                log_print('账单sql2',(Db::table('recharge'))->getLastSql());
                break;
            }else{
               /* if($v['is_fen'] == 1){
                    $fee =  $v['have_fee'];
                }else{
                    $fee =  $v['sharableAmount'];
                }*/
                //$fz_money = $fz_money - $use_sum;
                $fz_money = bcsub($fz_money, $use_sum,2);
                $log = [
                    'order_sn' => $order['order_sn'],
                    'bill_id' => $order['id'],
                    'fz_account' => $order['fz_account'],
                    'fz_number' => $order['fz_number'],
                    'mchId' => $v['mchId'],
                    'chnltrxid' => $v['chnltrxid'],
                    'recharge_order_sn' => $v['order_sn'],
                    'recharge_id' => $v['id'],
                    'fen_fee' => $use_sum,
                    'all_fee' => $v['sharableAmount'],
                    'sup_fee' => $fz_money,
                    'fen_sn' => $fen_sn,
                ];
                if($use_sum > 0){
                    BillLog::create($log);
                    log_print('账单sql1',(new BillLog())->getLastSql());
                    log_print('充值记录'.$v['id'].'总余额'.$v['sharableAmount'].'扣'.$use_sum.'剩余'.$fz_money.'未扣'.'-is_fen='.$v['is_fen']);
                    $up = [
                        'is_fen' => 2,
                        'have_fee' => 0,
                    ];
                    Db::table('recharge')
                        ->where('id',$v['id'])
                        ->update($up);
                    log_print('账单sql1',Db::table('recharge')->getLastSql());
                }
            }
        }




    }

    public static function rechargeFenConfig()
    {
        $config = config('db_zhongtai');
        $url = config('site.url');
        $conn = Db::connect($config);
        $row = $conn->table('app_manage')->where('url',$url)->find();
        $list = $conn->table('app_ledger')->where('type',6)->select();
        foreach ($list as &$v){
            $map = [
                "ledger_id" => $v['id'],
                "manage_id" => $row['id']
            ];
            $account = $conn->table('app_account')->where($map)->find();
            $v['fz_title'] = $v['name'];
            $percent = $v['proportion'];
            if($v['reduse_pro']){
                $percent = ($v['proportion']*100 - $v['reduse_pro']*100)/100;
            }
            $v['percent'] = $percent;
            $v['fz_number'] = $account?$account['code']:'';
        }
        if(empty($list)){
            log_print('充值分账账号为空');
        }
        return $list;
    }
}
